<template>
  <div
    ref="floatDrag"
    class="float-position"
    :style="{ left: left + 'px', top: top + 'px' }"
    @touchmove.prevent
    @mousemove.prevent
    @mousedown="mouseDown"
    @mouseup="mouseUp"
  >
    <a-popover title="意见反馈" trigger="click" class="cart">
      <template slot="content">
        <a-form :form="form" style="width: 600px;">
          <a-form-item
            :label-col="formItemLayout.labelCol"
            :wrapper-col="formItemLayout.wrapperCol"
            label="反馈类型"
          >
            <a-radio-group v-decorator="['type', {initialValue: '1'}]">
              <a-radio :value="1">
                问题
              </a-radio>
              <a-radio :value="2">
                建议
              </a-radio>
              <a-radio :value="3">
                其他
              </a-radio>
            </a-radio-group>
          </a-form-item>
          <a-form-item
            :label-col="formItemLayout.labelCol"
            :wrapper-col="formItemLayout.wrapperCol"
            label="内容"
          >
            <a-textarea v-decorator="['content', ValidateRules.content]"
                        placeholder="请输入您要反馈的内容（最多300字）"
                        :rows="6"
                        :maxLength="300"/>
          </a-form-item>
          <a-form-item
            :label-col="formItemLayout.labelCol"
            :wrapper-col="formItemLayout.wrapperCol"
            label="联系类型"
          >
            <a-radio-group v-decorator="['contactWay', {initialValue: '1'}]">
              <a-radio :value="1">
                QQ
              </a-radio>
              <a-radio :value="2">
                微信
              </a-radio>
              <a-radio :value="3">
                其他
              </a-radio>
            </a-radio-group>
          </a-form-item>
          <a-form-item
            :label-col="formItemLayout.labelCol"
            :wrapper-col="formItemLayout.wrapperCol"
            label="联系号码"
          >
            <a-input v-decorator="['contactNo']" placeholder="请输入您的联系号码"/>
          </a-form-item>
          <a-form-item
            :label-col="formTailLayout.labelCol"
            :wrapper-col="formTailLayout.wrapperCol"
          >
            <a-button type="primary" @click="checkAndSubmit">提交</a-button>
            <div v-if="ballVisibleSuccess">
              <a-icon type="check-circle" theme="filled" style="color: #13ce66"/>
              <span>提交成功,感谢您的反馈！</span>
            </div>
          </a-form-item>
        </a-form>
      </template>
      <span style="font-weight: bold; color: whitesmoke">意见反馈</span>
    </a-popover>
  </div>
</template>

<script>
import {addFeedBack} from '@/api/feedback'

const formItemLayout = {
  labelCol: {span: 5},
  wrapperCol: {span: 9}
};
const formTailLayout = {
  labelCol: {span: 4},
  wrapperCol: {span: 8, offset: 4}
};


export default {
  name: "floatBall",
  props: {
    distanceRight: {
      type: Number,
      default: 0
    },
    distanceBottom: {
      type: Number,
      default: 100
    },
    isScrollHidden: {
      type: Boolean,
      default: false
    },
    isCanDraggable: {
      type: Boolean,
      default: true
    },
    value: {
      type: String,
      default: "悬浮球！"
    }
  },
  data() {
    return {
      clientWidth: null,
      clientHeight: null,
      left: 0,
      top: 0,
      timer: null,
      currentTop: 0,
      mousedownX: 0,
      mousedownY: 0,
      ballVisibleSuccess: false,
      formItemLayout,
      formTailLayout,
      form: this.$form.createForm(this),
      ValidateRules: {
        content: {rules: [{required: true, message: '请输入您要反馈的内容'}]}
      }
    };
  },
  created() {
    this.clientWidth = document.documentElement.clientWidth;
    this.clientHeight = document.documentElement.clientHeight;
  },
  mounted() {
    this.isCanDraggable &&
    this.$nextTick(() => {
      this.floatDrag = this.$refs.floatDrag;
      // 获取元素位置属性
      this.floatDragDom = this.floatDrag.getBoundingClientRect();
      // 设置初始位置
      this.left =
        this.clientWidth - this.floatDragDom.width - this.distanceRight;
      this.top =
        this.clientHeight - this.floatDragDom.height - this.distanceBottom;
      this.initDraggable();
    });
    this.isScrollHidden && window.addEventListener("scroll", this.handleScroll);
    window.addEventListener("resize", this.handleResize);
  },
  methods: {
    checkAndSubmit() {
      this.form.validateFields(err => {
        if (!err) {
          addFeedBack(this.form.getFieldsValue()).then(res => {
            if (res.data.code === 20000) {
              this.ballVisibleSuccess = true
            }
          })
        }
      })
    },
    /**
     * 设置滚动监听
     * 设置滚动时隐藏悬浮按钮，停止时显示
     */
    handleScroll() {
      this.timer && clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        this.handleScrollEnd();
      }, 200);
      this.currentTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      if (this.left > this.clientWidth / 2) {
        // 判断元素位置再左侧还是右侧
        this.left = this.clientWidth + this.floatDragDom.width;
      } else {
        this.left = -this.floatDragDom.width;
      }
    },
    /**
     * 滚动结束
     */
    handleScrollEnd() {
      let scrollTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      if (scrollTop === this.currentTop) {
        console.log(this.left);
        if (this.left > this.clientWidth / 2) {
          // 判断元素位置再左侧还是右侧
          this.left = this.clientWidth - this.floatDragDom.width;
        } else {
          this.left = 0;
        }
        clearTimeout(this.timer);
      }
    },
    /**
     * 窗口resize监听
     */
    handleResize() {
      this.clientWidth = document.documentElement.clientWidth;
      this.clientHeight = document.documentElement.clientHeight;
      this.checkDraggablePosition();
    },
    /**
     * 初始化draggable
     */
    initDraggable() {
      this.floatDrag.addEventListener("touchstart", this.toucheStart);
      this.floatDrag.addEventListener("touchmove", e => this.touchMove(e));
      this.floatDrag.addEventListener("touchend", this.touchEnd);
    },
    mouseDown(e) {
      const event = e || window.event;
      this.mousedownX = event.screenX;
      this.mousedownY = event.screenY;
      const that = this;
      let floatDragWidth = this.floatDragDom.width / 2;
      let floatDragHeight = this.floatDragDom.height / 2;
      if (event.preventDefault) {
        event.preventDefault(); //event.preventDefault() 方法阻止元素发生默认的行为
      }
      this.canClick = false;
      this.floatDrag.style.transition = "none";
      document.onmousemove = function(e) {
        var event = e || window.event;
        that.left = event.clientX - floatDragWidth;
        that.top = event.clientY - floatDragHeight;
        if (that.left < 0) that.left = 0;
        if (that.top < 0) that.top = 0;
        if (that.left >= that.clientWidth - floatDragWidth * 2) {
          that.left = that.clientWidth - floatDragWidth * 2;
        }
        if (that.top >= that.clientHeight - floatDragHeight * 2) {
          that.top = that.clientHeight - floatDragHeight * 2;
        }
      };
    },
    // event.clientX、event.clientY 鼠标相对于浏览器窗口可视区域的X，Y坐标（窗口坐标），可视区域不包括工具栏和滚动条。
    // event.screenX、event.screenY鼠标相对于用户显示器屏幕左上角的X,Y坐标。
    // getBoundingClientRect()用于获得页面中某个元素的左，上，右和下分别相对浏览器视窗的位置。
    mouseUp(e) {
      const event = e || window.event;
      //判断只是单纯的点击，没有拖拽
      if (
        this.mousedownY == event.screenY &&
        this.mousedownX == event.screenX
      ) {
        // 关闭弹窗之后，提交成功消息隐藏
        this.ballVisibleSuccess = false
        this.$emit("handlepaly");
      }
      document.onmousemove = null;
      this.checkDraggablePosition();
      this.floatDrag.style.transition = "all 0.3s";
    },
    toucheStart() {
      this.canClick = false;
      this.floatDrag.style.transition = "none";
    },
    touchMove(e) {
      this.canClick = true;
      if (e.targetTouches.length === 1) {
        // 单指拖动
        let touch = event.targetTouches[0];
        this.left = touch.clientX - this.floatDragDom.width / 2;
        this.top = touch.clientY - this.floatDragDom.height / 2;
      }
    },
    touchEnd() {
      if (!this.canClick) return; // 解决点击事件和touch事件冲突的问题
      this.floatDrag.style.transition = "all 0.3s";
      this.checkDraggablePosition();
    },
    /**
     * 判断元素显示位置
     * 在窗口改变和move end时调用
     */
    checkDraggablePosition() {
      if (this.left + this.floatDragDom.width / 2 >= this.clientWidth / 2) {
        // 判断位置是往左往右滑动
        this.left = this.clientWidth - this.floatDragDom.width;
      } else {
        this.left = 0;
      }
      if (this.top < 0) {
        // 判断是否超出屏幕上沿
        this.top = 0;
      }
      if (this.top + this.floatDragDom.height >= this.clientHeight) {
        // 判断是否超出屏幕下沿
        this.top = this.clientHeight - this.floatDragDom.height;
      }
    }
  },
  beforeDestroy() {
    window.removeEventListener("scroll", this.handleScroll);
    window.removeEventListener("resize", this.handleResize);
  }
};
</script>

<style>
.float-position {
  position: absolute;
  z-index: 10003;
  right: 0;
  top: 70%;
  width: 3.6em;
  height: 3.6em;
  background: #f354a9;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0px 0px 10px 2px #34bfa3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.8em;
  user-select: none;
}
.cart {
  border-radius: 50%;
  width: 5em;
  height: 5em;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
